package dotsandboxs;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;

import javax.swing.JOptionPane;

public class AI {
    ChessGUI gui;
    int dot1, dot2, dot3, dot4;
    int flag = 1;

    @SuppressWarnings("static-access")
    public AI(ChessGUI gui) {
        this.gui = gui;
        while (flag == 1) {
            long a = System.nanoTime();
            dot1 = (int) (Math.random() * 6);// 获得0-5的随机数
            dot2 = (int) (Math.random() * 6);// 获得0-5的随机数
            dot3 = (int) (Math.random() * 6);// 获得0-5的随机数
            dot4 = (int) (Math.random() * 6);// 获得0-5的随机数
            int dotFirst = dot1 * 10 + dot2;
            int dotLast = dot3 * 10 + dot4;
            // 合法判断
            if (legalJudge(dotFirst, dotLast)) {
                // 进行大小交换，确保第一个数比第二个小
                if (dotFirst > dotLast) {
                    int t = dotFirst;
                    dotFirst = dotLast;
                    dotLast = t;
                }
                int tSide = getSide(dotFirst, dotLast);
                if (gui.color % 2 == 0) {
                    // 判断是否数组里面已经有这条边了
                    int isExist = 1;
                    for (int i = 0; i < ChessGUI.redSide.length; i++) {
                        if (tSide == ChessGUI.side[i]) {
                            isExist = 0;
                            continue;
                        }
                    }
                    if (isExist == 1) {
                        gui.g.setColor(Color.red);
                        drawLine(dotFirst, dotLast);// 以这两点划线
                        // 存储边
                        ChessGUI.side[ChessGUI.sideCount] = tSide;
                        ChessGUI.redSide[ChessGUI.redSideCount] = tSide;
                        ChessGUI.sideCount++;
                        ChessGUI.redSideCount++;
                        changeDOF(tSide); // 改变格子自由度
                        gui.color++;// 颜色计数器加1
                        gui.frame.repaint();// 重绘棋盘
                        flag = 0;
                    }
                } else if (gui.color % 2 == 1) {
                    // 判断是否数组里面已经有这条边了
                    int isExist = 1;
                    for (int i = 0; i < ChessGUI.blueSide.length; i++) {
                        if (tSide == ChessGUI.side[i]) {
                            isExist = 0;
                            continue;
                        }
                    }
                    if (isExist == 1) {
                        gui.g.setColor(Color.blue);
                        drawLine(dotFirst, dotLast);// 以这两点划线
                        // 存储边
                        ChessGUI.side[ChessGUI.sideCount] = tSide;
                        ChessGUI.blueSide[ChessGUI.blueSideCount] = tSide;
                        ChessGUI.sideCount++;
                        ChessGUI.blueSideCount++;
                        changeDOF(tSide); // 改变格子自由度
                        gui.color++;// 颜色计数器加1
                        gui.frame.repaint();// 重绘棋盘
                        flag = 0;
                    }
                }
                System.out.println("边存储成功，存储了：" + tSide);
                winLoseJudge();// 执行完代码之后调用判断输赢函数
                System.out.println("总耗时：" + (System.nanoTime() - a) + "ns");
            } // end legal
        } // end while
    }

    /**
     * 两个用二位数表示的点转成四位数表示一条边
     *
     * @param x 已经使用获得点函数转化之后的二位数点（第一个点）
     * @param y 已经使用获得点函数转化之后的二位数点（第二个点）
     * @return x * 100 + y
     */
    int getSide(int x, int y) {
        return x * 100 + y;
    }

    /**
     * 行棋合法性判断
     *
     * @param dotFirst 已经使用获得点函数转化之后的二位数点（第一个点）
     * @param dotLast  已经使用获得点函数转化之后的二位数点（第二个点）
     */
    boolean legalJudge(int dotFirst, int dotLast) {
        int xf = dotFirst / 10;
        int yf = dotFirst % 10;
        int xl = dotLast / 10;
        int yl = dotLast % 10;
        if (xf < 0 || yf < 0 || xl < 0 || yl < 0) {
            return false;
        }
        if ((xf - xl) == 0 && ((yf - yl) == -1 || (yf - yl) == 1))
            return true;
        else if (((xf - xl) == -1 || (xf - xl) == 1) && (yf - yl) == 0)
            return true;
        else
            return false;
    }

    /**
     * 两点连线函数
     *
     * @param dotFirst 已经使用获得点函数转化之后的二位数点（第一个点）
     * @param dotLast  已经使用获得点函数转化之后的二位数点（第二个点）
     */
    void drawLine(int dotFirst, int dotLast) {
        int xf = dotFirst / 10;
        int yf = dotFirst % 10;
        int xl = dotLast / 10;
        int yl = dotLast % 10;
        Graphics2D g2d = (Graphics2D) gui.g;
        g2d.setStroke(new BasicStroke(5.5f));
        // 像素-1是为了更加契合棋盘
        gui.g.drawLine(xf * 100 + ChessGUI.INITWIDTH - 1, yf * 100 + ChessGUI.INITHEIGHT - 1,
                xl * 100 + ChessGUI.INITWIDTH - 1, yl * 100 + ChessGUI.INITHEIGHT - 1);
    }

    // 格子自由度的变化 传入一条边（一个4位数的整型） ---------已经通过测试无误
    @SuppressWarnings("static-access")
    /**
     * 格子自由度的变化函数
     *
     * @param side 用转换边函数得到的一个四位数
     */
    void changeDOF(int side) {
        // 拆分成坐标
        int dotFirst = side / 100;
        int dotLast = side % 100;
        int xf = dotFirst / 10;
        int yf = dotFirst % 10;
        int xl = dotLast / 10;
        int yl = dotLast % 10;
        // 建立点和格子的联系
        // 是边界，else就不是边界的
        if (xl == xf && xf == 0 || xl == xf && xf == 5 || yl == yf && yf == 0 || yl == yf && yf == 5) {
            if (xl == xf) {
                int index = 5 * yl + xl * xl - 21 * xl / 5 - 5;
                ChessGUI.block[index]++;
                if (addBox(ChessGUI.block, index)) {
                    gui.color++;// 因为占领一个格子之后要再下一条边
                }
            } // 纵向
            if (yl == yf) {
                ChessGUI.block[4 * yl + xl - 1]++;
                if (addBox(ChessGUI.block, 4 * yl + xl - 1)) {
                    gui.color++;// 因为占领一个格子之后要再下一条边
                }
            } // 横向
        } else {
            if (xl == xf) {
                ChessGUI.block[5 * yl + xl - 6]++;// 左边
                boolean flag1 = addBox(ChessGUI.block, 5 * yl + xl - 6);
                ChessGUI.block[5 * yl + xl - 5]++;// 右边
                boolean flag2 = addBox(ChessGUI.block, 5 * yl + xl - 5);
                if (flag1 || flag2) {
                    gui.color++;// 因为占领一个格子之后要再下一条边
                }
            } // 纵向
            if (yl == yf) {
                ChessGUI.block[5 * yl + xl - 6]++;// 上面
                boolean flag1 = addBox(ChessGUI.block, 5 * yl + xl - 6);
                ChessGUI.block[5 * yl + xl - 1]++;// 下面
                boolean flag2 = addBox(ChessGUI.block, 5 * yl + xl - 1);
                if (flag1 || flag2) {
                    gui.color++;// 因为占领一个格子之后要再下一条边
                }
            } // 横向
        }
    }

    /**
     * 存储格子进入数组函数
     *
     * @param block 格子数组
     * @param index 格子的下标
     */
    @SuppressWarnings("static-access")
    boolean addBox(int[] block, int index) {
        if (block[index] == 4) {
            // 判断行棋方
            if (gui.color % 2 == 0) {
                // 判断下标是否为0，如果是则赋值为-1，否则就赋值为原来的下标
                if (index == 0) {
                    gui.redBox[ChessGUI.redBoxCount] = index - 1;
                } else {
                    gui.redBox[ChessGUI.redBoxCount] = index;
                }
                ChessGUI.redBoxCount++;
                ChessGUI.redBlock++;
            } else {
                // 判断下标是否为0，如果是则赋值为-1，否则就赋值为原来的下标
                if (index == 0) {
                    gui.blueBox[ChessGUI.blueBoxCount] = index - 1;
                } else {
                    gui.blueBox[ChessGUI.blueBoxCount] = index;
                }
                ChessGUI.blueBoxCount++;
                ChessGUI.blueBlock++;
            }
            return true;
        } else {
            return false;
        }

    }

    /**
     * 输赢判断函数
     *
     */
    void winLoseJudge() {
        if (ChessGUI.redBlock + ChessGUI.blueBlock == 25) {
            // 标志游戏结束
            if (ChessGUI.redBlock > ChessGUI.blueBlock) {
                JOptionPane.showMessageDialog(gui.frame, "红方胜利！请重新开始游戏", "胜利", JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(gui.frame, "蓝方胜利！请重新开始游戏", "胜利", JOptionPane.INFORMATION_MESSAGE);
            }
            ChessGUI.gameMode = 0;// 标志游戏结束
        }

    }

}
